home *** CD-ROM | disk | FTP | other *** search
/ 17 Bit Software 6: Level 6 / 17 Bit - Level 6 (1998)(Epic Marketing)[!].iso / quartz / q1082.dms / q1082.adf / src.lzh / Fig / spline.c < prev    next >
C/C++ Source or Header  |  1991-07-18  |  5KB  |  194 lines

  1. /* 
  2.  *    FIG : Facility for Interactive Generation of figures
  3.  *
  4.  *    Copyright (c) 1985 by Supoj Sutanthavibul (supoj@sally.UTEXAS.EDU)
  5.  *    January 1985.
  6.  *    1st revision : Aug 1985, Add closed spline.
  7.  *
  8.  *    %W%    %G%
  9. */
  10. #include "fig.h"
  11. #include "resources.h"
  12. #include "alloc.h"
  13. #include "func.h"
  14. #include "object.h"
  15. #include "paintop.h"
  16.  
  17. extern            (*canvas_kbd_proc)();
  18. extern            (*canvas_locmove_proc)();
  19. extern            (*canvas_leftbut_proc)();
  20. extern            (*canvas_middlebut_proc)();
  21. extern            (*canvas_rightbut_proc)();
  22. extern            null_proc();
  23. extern            set_popupmenu();
  24.  
  25. extern int        cur_line_style, line_thickness;
  26. extern float        cur_styleval;
  27. extern int        cur_color;
  28. extern int        fix_x, fix_y, cur_x, cur_y;
  29. extern int        cur_command;
  30. extern int        manhattan_mode, mountain_mode;
  31. extern int        autoforwardarrow_mode;
  32. extern int        autobackwardarrow_mode;
  33. extern int        arrow_ht, arrow_wid;
  34. extern F_compound    objects;
  35. extern int        num_point;
  36. extern int        DEBUG;
  37. extern F_point        *first_point, *cur_point;
  38.  
  39. int            create_splineobject();
  40.             init_spline_drawing();
  41.  
  42. draw_spline_selected()
  43. {
  44.     canvas_kbd_proc = null_proc;
  45.     canvas_locmove_proc = null_proc;
  46.     canvas_leftbut_proc = init_spline_drawing;
  47.     canvas_middlebut_proc = null_proc;
  48.     canvas_rightbut_proc = set_popupmenu;
  49.     set_cursor(&arrow_cursor);
  50.     reset_action_on();
  51.     }
  52.  
  53. init_spline_drawing(x, y)
  54. int    x, y;
  55. {
  56.     init_line_drawing(x, y);
  57.     canvas_middlebut_proc = create_splineobject;
  58.     canvas_rightbut_proc = null_proc;
  59.     }
  60.  
  61. create_splineobject(x, y)
  62. int    x, y;
  63. {
  64.     extern F_arrow    *forward_arrow(), *backward_arrow();
  65.     F_spline    *spline;
  66.  
  67.     if (x != fix_x || y != fix_y) get_intermediatepoint(x, y);
  68.     draw_elasticline();
  69.     if (num_point <= 2) {
  70.         pw_vector(canvas_pixwin, first_point->x, first_point->y,
  71.             cur_point->x, cur_point->y, PAINT, 0);
  72.         if (num_point == 1) free((char*)cur_point);
  73.         free((char*)first_point);
  74.         draw_spline_selected();
  75.         return;
  76.         }
  77.     Spline_malloc(spline);
  78.     spline->style = cur_line_style;
  79.     spline->thickness = line_thickness;
  80.     spline->style_val = cur_styleval;
  81.     spline->color = cur_color;
  82.     spline->depth = 0;
  83.     spline->pen = NULL;
  84.     spline->area_fill = NULL;
  85.     spline->points = first_point;
  86.     spline->controls = NULL; 
  87.     spline->next = NULL; 
  88.     cur_x = cur_y = fix_x = fix_y = 0; /* used in draw_movingpoint */
  89.     draw_movingpoint(spline->points, INV_PAINT); /* erase control vector */
  90.     pw_batch_on(canvas_pixwin);
  91.     if (cur_command == F_CLOSED_SPLINE) {
  92.         spline->type = T_CLOSED_NORMAL;
  93.         spline->for_arrow = NULL;
  94.         spline->back_arrow = NULL;
  95.         num_point++;
  96.         append_point(first_point->x, first_point->y, &cur_point);
  97.         draw_closed_spline(spline, PAINT);
  98.         }
  99.     else {    /* It must be F_SPLINE */
  100.         if (autoforwardarrow_mode)
  101.         spline->for_arrow = forward_arrow();
  102.         else
  103.         spline->for_arrow = NULL;
  104.         if (autobackwardarrow_mode)
  105.         spline->back_arrow = backward_arrow();
  106.         else
  107.         spline->back_arrow = NULL;
  108.         spline->type = T_OPEN_NORMAL;
  109.         draw_open_spline(spline, PAINT);
  110.         }
  111.     pw_batch_off(canvas_pixwin);
  112.     if (DEBUG) {
  113.         int        xmin, ymin, xmax, ymax;
  114.         spline_bound(spline, &xmin, &ymin, &xmax, &ymax);
  115.         draw_rectbox(xmin, ymin, xmax, ymax, PAINT);
  116.         }
  117.     clean_up();
  118.     insert_spline(&objects.splines, spline);
  119.     set_action_object(F_CREATE, O_SPLINE);
  120.     set_latestspline(spline);
  121.     set_modifiedflag();
  122.     draw_spline_selected();
  123.     }
  124.  
  125. #define            round(x)        ((int) (x + .5))
  126.  
  127. draw_open_spline(spline, op)
  128. F_spline    *spline;
  129. int        op;
  130. {
  131.     F_point    *p;
  132.     float    cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
  133.     float    x1, y1, x2, y2;
  134.  
  135.     p = spline->points;
  136.     x1 = p->x;  y1 = p->y;
  137.     p = p->next;
  138.     x2 = p->x;  y2 = p->y;
  139.     cx1 = (x1 + x2) / 2;      cy1 = (y1 + y2) / 2;
  140.     cx2 = (cx1 + x2) / 2;  cy2 = (cy1 + y2) / 2;
  141.     if (spline->back_arrow) /*  backward arrow  */
  142.         draw_arrow((int)x2, (int)y2, (int)x1, (int)y1, 
  143.         spline->back_arrow, op);
  144.     pw_vector(canvas_pixwin, (int)x1, (int)y1, round(cx1), 
  145.         round(cy1), op, 1);
  146.  
  147.     for (p = p->next; p != NULL; p = p->next) {
  148.         x1 = x2;  y1 = y2;
  149.         x2 = p->x;  y2 = p->y;
  150.         cx4 = (x1 + x2) / 2; cy4 = (y1 + y2) / 2;
  151.         cx3 = (x1 + cx4) / 2; cy3 = (y1 + cy4) / 2;
  152.         quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4, op);
  153.         cx1 = cx4;  cy1 = cy4;
  154.         cx2 = (cx1 + x2) / 2;  cy2 = (cy1 + y2) / 2;
  155.         }
  156.     pw_vector(canvas_pixwin, round(cx1), round(cy1), 
  157.         (int)x2, (int)y2, op, 1);
  158.     if (spline->for_arrow) /*  forward arrow  */
  159.         draw_arrow((int)x1, (int)y1, (int)x2, (int)y2, 
  160.         spline->for_arrow, op);
  161.     }
  162.  
  163. draw_closed_spline(spline, op)
  164. F_spline    *spline;
  165. int        op;
  166. {
  167.     F_point    *p;
  168.     float    cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
  169.     float    x1, y1, x2, y2;
  170.  
  171.     p = spline->points;
  172.     x1 = p->x;  y1 = p->y;
  173.     p = p->next;
  174.     x2 = p->x;  y2 = p->y;
  175.     cx1 = (x1 + x2) / 2;      cy1 = (y1 + y2) / 2;
  176.     cx2 = (x1 + 3 * x2) / 4;  cy2 = (y1 + 3 * y2) / 4;
  177.  
  178.     for (p = p->next; p != NULL; p = p->next) {
  179.         x1 = x2;  y1 = y2;
  180.         x2 = p->x;  y2 = p->y;
  181.         cx4 = (x1 + x2) / 2;   cy4 = (y1 + y2) / 2;
  182.         cx3 = (x1 + cx4) / 2;  cy3 = (y1 + cy4) / 2;
  183.         quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4, op);
  184.         cx1 = cx4;  cy1 = cy4;
  185.         cx2 = (cx1 + x2) / 2;  cy2 = (cy1 + y2) / 2;
  186.         }
  187.     x1 = x2;  y1 = y2;
  188.     p = spline->points->next;
  189.     x2 = p->x;  y2 = p->y;
  190.     cx4 = (x1 + x2) / 2;   cy4 = (y1 + y2) / 2;
  191.     cx3 = (x1 + cx4) / 2;  cy3 = (y1 + cy4) / 2;
  192.     quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4, op);
  193.     }
  194.